﻿using System;
using System.Collections;
using UnityEngine;

namespace RootMotion.FinalIK
{
	// Token: 0x020001C2 RID: 450
	public abstract class OffsetModifier : MonoBehaviour
	{
		// Token: 0x170000BD RID: 189
		// (get) Token: 0x0600094C RID: 2380 RVA: 0x000310AD File Offset: 0x0002F4AD
		protected float deltaTime
		{
			get
			{
				return Time.time - this.lastTime;
			}
		}

		// Token: 0x0600094D RID: 2381
		protected abstract void OnModifyOffset();

		// Token: 0x0600094E RID: 2382 RVA: 0x000310BB File Offset: 0x0002F4BB
		protected virtual void Start()
		{
			base.StartCoroutine(this.Initiate());
		}

		// Token: 0x0600094F RID: 2383 RVA: 0x000310CC File Offset: 0x0002F4CC
		private IEnumerator Initiate()
		{
			while (this.ik == null)
			{
				yield return null;
			}
			IKSolverFullBodyBiped solver = this.ik.solver;
			solver.OnPreUpdate = (IKSolver.UpdateDelegate)Delegate.Combine(solver.OnPreUpdate, new IKSolver.UpdateDelegate(this.ModifyOffset));
			this.lastTime = Time.time;
			yield break;
		}

		// Token: 0x06000950 RID: 2384 RVA: 0x000310E8 File Offset: 0x0002F4E8
		private void ModifyOffset()
		{
			if (!base.enabled)
			{
				return;
			}
			if (this.weight <= 0f)
			{
				return;
			}
			if (this.deltaTime <= 0f)
			{
				return;
			}
			if (this.ik == null)
			{
				return;
			}
			this.weight = Mathf.Clamp(this.weight, 0f, 1f);
			this.OnModifyOffset();
			this.lastTime = Time.time;
		}

		// Token: 0x06000951 RID: 2385 RVA: 0x00031164 File Offset: 0x0002F564
		protected void ApplyLimits(OffsetModifier.OffsetLimits[] limits)
		{
			foreach (OffsetModifier.OffsetLimits offsetLimits in limits)
			{
				offsetLimits.Apply(this.ik.solver.GetEffector(offsetLimits.effector), base.transform.rotation);
			}
		}

		// Token: 0x06000952 RID: 2386 RVA: 0x000311B2 File Offset: 0x0002F5B2
		protected virtual void OnDestroy()
		{
			if (this.ik != null)
			{
				IKSolverFullBodyBiped solver = this.ik.solver;
				solver.OnPreUpdate = (IKSolver.UpdateDelegate)Delegate.Remove(solver.OnPreUpdate, new IKSolver.UpdateDelegate(this.ModifyOffset));
			}
		}

		// Token: 0x04000602 RID: 1538
		[Tooltip("The master weight")]
		public float weight = 1f;

		// Token: 0x04000603 RID: 1539
		[Tooltip("Reference to the FBBIK component")]
		public FullBodyBipedIK ik;

		// Token: 0x04000604 RID: 1540
		protected float lastTime;

		// Token: 0x020001C3 RID: 451
		[Serializable]
		public class OffsetLimits
		{
			// Token: 0x06000954 RID: 2388 RVA: 0x000311FC File Offset: 0x0002F5FC
			public void Apply(IKEffector e, Quaternion rootRotation)
			{
				Vector3 point = Quaternion.Inverse(rootRotation) * e.positionOffset;
				if (this.spring <= 0f)
				{
					if (this.x)
					{
						point.x = Mathf.Clamp(point.x, this.minX, this.maxX);
					}
					if (this.y)
					{
						point.y = Mathf.Clamp(point.y, this.minY, this.maxY);
					}
					if (this.z)
					{
						point.z = Mathf.Clamp(point.z, this.minZ, this.maxZ);
					}
				}
				else
				{
					if (this.x)
					{
						point.x = this.SpringAxis(point.x, this.minX, this.maxX);
					}
					if (this.y)
					{
						point.y = this.SpringAxis(point.y, this.minY, this.maxY);
					}
					if (this.z)
					{
						point.z = this.SpringAxis(point.z, this.minZ, this.maxZ);
					}
				}
				e.positionOffset = rootRotation * point;
			}

			// Token: 0x06000955 RID: 2389 RVA: 0x0003133C File Offset: 0x0002F73C
			private float SpringAxis(float value, float min, float max)
			{
				if (value > min && value < max)
				{
					return value;
				}
				if (value < min)
				{
					return this.Spring(value, min, true);
				}
				return this.Spring(value, max, false);
			}

			// Token: 0x06000956 RID: 2390 RVA: 0x00031368 File Offset: 0x0002F768
			private float Spring(float value, float limit, bool negative)
			{
				float num = value - limit;
				float num2 = num * this.spring;
				if (negative)
				{
					return value + Mathf.Clamp(-num2, 0f, -num);
				}
				return value - Mathf.Clamp(num2, 0f, num);
			}

			// Token: 0x04000605 RID: 1541
			[Tooltip("The effector type (this is just an enum)")]
			public FullBodyBipedEffector effector;

			// Token: 0x04000606 RID: 1542
			[Tooltip("Spring force, if zero then this is a hard limit, if not, offset can exceed the limit.")]
			public float spring;

			// Token: 0x04000607 RID: 1543
			[Tooltip("Which axes to limit the offset on?")]
			public bool x;

			// Token: 0x04000608 RID: 1544
			[Tooltip("Which axes to limit the offset on?")]
			public bool y;

			// Token: 0x04000609 RID: 1545
			[Tooltip("Which axes to limit the offset on?")]
			public bool z;

			// Token: 0x0400060A RID: 1546
			[Tooltip("The limits")]
			public float minX;

			// Token: 0x0400060B RID: 1547
			[Tooltip("The limits")]
			public float maxX;

			// Token: 0x0400060C RID: 1548
			[Tooltip("The limits")]
			public float minY;

			// Token: 0x0400060D RID: 1549
			[Tooltip("The limits")]
			public float maxY;

			// Token: 0x0400060E RID: 1550
			[Tooltip("The limits")]
			public float minZ;

			// Token: 0x0400060F RID: 1551
			[Tooltip("The limits")]
			public float maxZ;
		}
	}
}
